import logging
import os
import webapp2

from db import model
from db.student_client import StudentClient
from db.survey_client import SurveyClient

from google.appengine.api import taskqueue
from google.appengine.ext import db
from google.appengine.ext.webapp import template

#===================================================================
# To begin a new session enter the follow url into a web browser:
# https://muresidencestudy.appspot.com/task/create_session?start=1
#===================================================================

class CreateSession(webapp2.RequestHandler):
  def __init__(self, request, response):
    self.initialize(request, response)
    self.student_client = StudentClient()
    self.survey_client = SurveyClient()

  def get(self):
    path = os.path.join(os.path.dirname(__file__), 'create_session.html')
    if self.request.get('start'):
      taskqueue.add(url='/task/create_session')
      self.response.out.write(template.render(path, {'start': 'task started'}))
    else:
      self.response.out.write(template.render(path, {'start': ''}))

  def post(self):
    pass
 #   self.student_client.loadStudents(is_new_year=False)

  def cloneStudents(self):
    def txn():
      # If any students have already been added to this session then don't do
      # anything (that means they are being added via another task).
      if not self.__isCurrentSessionCreated(model.Student):
        model.updateModelsInBatches(model.Student, self.cloneStudent,
            session='2012-01')
    db.run_in_transaction(txn)

  def cloneStudent(self, student):
    clone = student.clone()
    clone.session = model.CURRENT_SESSION
    clone.status = None
    clone.previous_session_status = student.status
    return clone

  def cloneFriendSurveys(self):
    # If any friend surveys have already been added to this session then don't
    # do anything (that means they are being added via another task).
    if not self.__isCurrentSessionCreated(model.FriendSurvey):
      model.updateModelsInBatches(model.FriendSurvey, self.cloneFriendSurvey,
          session='2012-01')

  def cloneFriendSurvey(self, friend_survey):
    clone = friend_survey.clone()
    clone.session = model.CURRENT_SESSION
    # The clone contains a reference to the friend from the previous session.
    # Update with the correct friend reference.
    friend_in_session = self.student_client.getStudentByEmail(
        clone.friend.email_address)
    clone.friend = friend_in_session
    # We also need to update the student ID for the student of the current
    # session.
    student = self.student_client.getStudent(clone.student_id)
    student_in_session = self.student_client.getStudentByEmail(
        student.email_address)
    clone.student_id = student_in_session.key().id()
    return clone

  def updateAnswers(self):
    model.updateModelsInBatches(model.Answer, self.updateSession)

  def updateFriendSurveys(self):
    model.updateModelsInBatches(model.FriendSurvey, self.updateSession)

  def updateStrainedFriendSurveys(self):
    model.updateModelsInBatches(model.StrainedFriendSurvey, self.updateSession)

  def updateSession(self, db_model):
    db_model.session = model.CURRENT_SESSION
    return db_model

  def __isCurrentSessionCreated(self, model_class):
    query = model_class.all()
    query.ancestor(model_class.gen_key())
    query.filter("session = ", model.CURRENT_SESSION)
    if query.get():
      return True
    return False

  def updateStudentIds(self):
    student_id_map = self.createStudentIdDupMap()

    students = self.student_client.getStudents()
    update_queue = []
    for student in students:
      if student_id_map.has_key(student.key().id()):
        student.deleted = True
      else:
        student.deleted = False
      update_queue.append(student)
      if len(update_queue) == 500:
        logging.info('updating ' + str(len(update_queue)))
        db.put(update_queue)
        update_queue = []
    if len(update_queue) > 0:
      logging.info('updating ' + str(len(update_queue)))
      db.put(update_queue)

  def createStudentIdDupMap(self):
    student_map = {}
    for student in self.student_client.getStudents():
      if student_map.has_key(student.email_address):
        student_map[student.email_address].append(student.key().id())
      else:
        student_map[student.email_address] = [student.key().id()]

    # Sort student IDs (lowest ID is the "primary" ID).
    for student_ids in student_map.values():
      student_ids.sort()

    # Create ID map.
    student_id_map = {}
    for student_ids in student_map.values():
      primary_student_id = student_ids[0]
      for student_id in student_ids:
        if student_id != primary_student_id:
          student_id_map[student_id] = primary_student_id

    return student_id_map


app = webapp2.WSGIApplication([
  ('/task/create_session', CreateSession)
], debug=True)
